home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / asm3.zip / PUSHDIR.ASM < prev    next >
Assembly Source File  |  1986-03-03  |  6KB  |  198 lines

  1. main    group    code
  2. code    segment    public    para    'code'
  3. assume    cs:main
  4.  
  5. org    100h                ;.COM file
  6.  
  7. BEGIN:    jmp    START            ;program starts here
  8.         db    "Copyright 1986 Ziff-Davis Publishing Co.",1Ah
  9. signature    db    'PUSHDIR VERSION 1.0'
  10. lengthsignature = $ - signature
  11.  
  12. savedint16    dd    ?        ;old int 16h vector
  13.  
  14. nextpush    dw    offset main:push1dir    ;next place to save a dir
  15. push1dir    db    67 dup (0)        ;storage for a saved dir
  16. push2dir    db    67 dup (0)        ;more storage
  17. push3dir    db    67 dup (0)        ;more storage
  18. push4dir    db    67 dup (0)        ;more storage
  19. push5dir    db    67 dup (0)        ;more storage
  20. push6dir    db    67 dup (0)        ;last storage
  21.  
  22. ;up to here must be EXACTLY identical in both PUSHDIR and POPDIR so that
  23. ;popdir can know how to access the memory space reserved by the first
  24. ;pushdir.
  25.  
  26. ;myint16 is an interrupt handler chained onto the existing interrupt handler.
  27. ;it is used to find out if PUSHDIR is already installed and if it is, where
  28. ;is it located?  It works by adding another function to int 16h.  To use it
  29. ;ax = 7788h, bx = 7789h, and ds:si points to the signature string.  If any one
  30. ;of these conditions is not true, then the int 16h call is passed onto the
  31. ;old routine without doing anything.  If they are all true, then we switch
  32. ;ax and bx and return ds = code segment (cs) of the interrupt handler.
  33.  
  34. myint16    proc    far
  35.  
  36.     pushf                ;save flags
  37.     cmp    ax,7788h            ;possible signature request ?
  38.     je    CHECKSIG            ;yes
  39. NOTSIG:
  40.     popf                ;no - recover flags
  41.     jmp    cs:[savedint16]        ;go to old routine as normal
  42.  
  43. CHECKSIG:
  44.     cmp    bx,7789h        ;possible signature request ?
  45.     jne    NOTSIG            ;no
  46.  
  47.     ;ax and bx were correct for a signature request
  48.     ;now see if ds:si was pointing to the signature string
  49.     ;the whole idea of the signature is that is has to be
  50.     ;totally unique so no other program could possibly use the same one.
  51.  
  52.     push    es            ;save the registers we will use
  53.     push    di
  54.     push    cx 
  55.     mov    di,offset main:signature    ;address of the signature
  56.     mov    cx,lengthsignature        ;length of the signature
  57.     repe    cmpsb            ;does string at ds:si match es:di ?
  58.     pop    cx            ;recover all registers we used
  59.     pop    di
  60.     pop    es
  61.     jne    NOTSIG            ;no, not correct signature
  62.  
  63. ;yes, it was a signature request so return ds equal to the current code
  64. ;segment so subsequent pushdir's and popdir's know where the original
  65. ;is located.
  66.  
  67.     push    cs
  68.     pop    ds            ;set ds = cs
  69.     xchg    ax,bx            ;flip these two so we know that
  70.                     ;ds is being returned
  71.     popf                ;recover original flags
  72.     iret                ;return back to the program
  73.                     ;that called the int 16h
  74.  
  75. myint16    endp
  76.  
  77. endresident    label    byte        ;label marking the end of the
  78.                     ;code to remain resident
  79.  
  80. ;code after here will not remain resident
  81.  
  82. install        db    1    ;0 = already installed, 1 = not installed
  83.  
  84. abortmsg    db    'Error reading the current directory.$'
  85. installmsg    db    'PUSHDIR installed.$'
  86.  
  87. START:
  88.     sti                ;turn interrupts on
  89.  
  90.     ;first check to see if PUSHDIR is already installed
  91.  
  92.     mov    ax,7788h            ;signature request
  93.     mov    bx,7789h            ;signature request
  94.     mov    si,offset main:signature    ;point to signature
  95.     int    16h            ;is it installed ?
  96.     
  97. assume    ds:nothing
  98.     
  99.     cmp    bx,7788h            ;were ax and bx switched ?
  100.     jne    NOTINSTALLED        ;no
  101.     cmp    ax,7789h            ;were ax and bx switched ?
  102.     jne    NOTINSTALLED        ;no
  103.     
  104.     ;yes it is installed already
  105.  
  106.     mov    cs:[install],0        ;don't install it again
  107. NOTINSTALLED:
  108.     
  109.     ;ds = segment of the installation
  110.     
  111.     ;store the current directory, including disk drive letter
  112.     
  113.     mov    si,ds:[nextpush]    ;get storage address for next push
  114.     add    si,3            ;make room for d:\
  115.     mov    dl,0            ;default drive
  116.     mov    ah,47h            ;dos function number
  117.     int    21h            ;get current directory
  118.     jc    ABORTERR        ;error message if carry set
  119.     mov    ah,19h            ;dos function number
  120.     int    21h            ;get the current drive
  121.     add    al,'A'            ;convert to ascii
  122.     mov    byte ptr ds:[si-3],al    ;add the "D:\" in front of path
  123.     mov    byte ptr ds:[si-2],':'
  124.     mov    byte ptr ds:[si-1],'\'
  125.  
  126.     ;now update [nextpush] for the next PUSHDIR
  127.  
  128.     cmp    ds:[nextpush],offset main:push6dir    ;time to wrap around ?
  129.     je    WRAPPUSH                ;yes
  130.     add    ds:[nextpush],67            ;no, point to next one
  131.     jmp    short GOTNEXTPUSH 
  132. WRAPPUSH:
  133.     mov    ds:[nextpush],offset main:push1dir    ;wrap back to beginning
  134. GOTNEXTPUSH:
  135.     cmp    cs:[install],1            ;should we install it
  136.     je    DOINSTALL                ;yes
  137.     int    20h                ;no, we are done
  138.  
  139. ABORTERR:
  140.     mov    dx,offset main:abortmsg        ;address of error message
  141.     mov    ah,9                ;dos function number
  142.     int    21h                ;show error message
  143.     int    20h                ;end program on error
  144.  
  145.  
  146.     ;if we got to here, then pushdir is not already installed,
  147.     ;so we need to install it by making part of it memory resident.
  148.  
  149. DOINSTALL:
  150.     push    cs
  151.     pop    ds            ;set ds = cs
  152.  
  153. assume    ds:main
  154.  
  155.     ;save the current int 16h vector
  156.  
  157.     push    es            ;save es
  158.     mov    ax,3516h            ;dos function 35h, vector 16h
  159.     int    21h            ;get the existing vector into es:bx
  160.     mov    word ptr [savedint16],bx    ;save es:bx
  161.     mov    word ptr [savedint16+2],es    ;save es:bx
  162.     pop    es            ;recover es
  163.  
  164.     ;now set the new int 16h vector to point to my routine
  165.  
  166.     mov    dx,offset main:myint16    ;point to my new routine
  167.     mov    ax,2516h            ;dos function 25h, vector 16h
  168.     int    21h            ;set new vector to ds:dx
  169.  
  170.     ;now show a message on the screen
  171.     ;this message can be suppressed by redirecting output to NUL
  172.     ;by using pushdir like this: PUSHDIR >NUL
  173.  
  174.     mov    dx,offset main:installmsg
  175.     mov    ah,9
  176.     int    21h            ;show installation message
  177.  
  178.     ;now free up the memory occupied by the envirnoment so it is not
  179.     ;permanently wasted
  180.  
  181.     mov    ax,ds:[2ch]        ;get segment of environment
  182.     mov    es,ax            ;load envirnoment segment into es
  183.     mov    ah,49h            ;dos function number
  184.     int    21h            ;free the environment memory
  185.  
  186.     ;now terminate resident protecting only the first part of this program
  187.  
  188.     mov    dx,offset main:endresident    ;point to end of resident code
  189.     add    dx,0fh            ;round up
  190.     mov    cl,4
  191.     shr    dx,cl            ;convert to paragraphs (divide by 16)
  192.     mov    ax,3100h        ;dos function 31h, error code=0
  193.     int    21h            ;terminate and remain resident
  194.  
  195. code    ends
  196. end    begin                ;start execution at BEGIN
  197.  
  198.